import { reactive } from "vue";
import { ElMessage } from "element-plus";
import { colorUtil } from "@fast-china/utils";
import { defineStore } from "pinia";

export type IAnimationName =
	| "slide-right"
	| "slide-left"
	| "el-fade-in-linear"
	| "el-fade-in"
	| "el-zoom-in-center"
	| "el-zoom-in-top"
	| "el-zoom-in-bottom";

const defaultAnimation: IAnimationName = "slide-right";
export const defaultThemeColor = "#409EFF";

const defaultLayoutSize = {
	mainPadding: "5px",
	footerHeight: "30px",
};

const smallLayoutSize = {
	mainPadding: "3px",
	footerHeight: "25px",
};

export const useConfig = defineStore(
	"config",
	() => {
		/**
		 * 布局配置
		 */
		const layout = reactive({
			/** 主页面内容 padding */
			mainPadding: "5px",
			/** 页脚高度 */
			footerHeight: "30px",
			/** 切换动画 */
			mainAnimation: defaultAnimation,
			/** 主题颜色 */
			themeColor: defaultThemeColor,
			/** 跟随系统设置，自动切换浅色/深色模式 */
			autoThemMode: true,
			/** 是否深色模式 */
			isDark: false,
			/** 是否置灰模式 */
			isGrey: false,
			/** 是否色弱模式 */
			isWeak: false,
		});

		/**
		 * 设置主题色
		 */
		const setTheme = (color: string): void => {
			if (!color) {
				color = defaultThemeColor;
				ElMessage({ type: "success", message: `主题颜色已重置为 ${defaultThemeColor}` });
			}
			// 计算主题颜色变化
			document.documentElement.style.setProperty("--el-color-primary", color);
			for (let i = 1; i <= 9; i++) {
				const primaryColor = layout.isDark ? `${colorUtil.getDarkColor(color, i / 10)}` : `${colorUtil.getLightColor(color, i / 10)}`;
				document.documentElement.style.setProperty(`--el-color-primary-light-${i}`, primaryColor);
			}
			for (let i = 1; i <= 9; i++) {
				const primaryColor = layout.isDark ? `${colorUtil.getDarkColor(color, i / 10)}` : `${colorUtil.getLightColor(color, i / 10)}`;
				document.documentElement.style.setProperty(`--el-color-primary-dark-${i}`, primaryColor);
			}
			layout.themeColor = color;
		};

		const darkModeMediaQuery = window.matchMedia("(prefers-color-scheme: dark)");

		/**
		 * 切换深色模式
		 */
		const switchDark = (): void => {
			const html = document.documentElement;
			if (layout.isDark) {
				html.classList.add("dark");
			} else {
				html.classList.remove("dark");
			}
			setTheme(layout.themeColor);
		};

		/**
		 * 切换跟随系统变化自动设置浅色/深色模式
		 */
		const switchAutoThemMode = (): void => {
			if (layout.autoThemMode) {
				// 判断是否启用深色模式
				if (darkModeMediaQuery.matches) {
					layout.isDark = true;
				} else {
					layout.isDark = false;
				}
				switchDark();
			}
		};

		/**
		 * 切换置灰或色弱模式
		 */
		const switchGreyOrWeak = (type: "grey" | "weak", value: boolean): void => {
			const body = document.body;
			if (!value) return body.removeAttribute("style");
			const styles: Record<"grey" | "weak", string> = {
				grey: "filter: grayscale(1)",
				weak: "filter: invert(80%)",
			};
			body.setAttribute("style", styles[type]);
			switch (type) {
				case "grey":
					layout.isGrey = true;
					layout.isWeak = false;
					break;
				case "weak":
					layout.isGrey = false;
					layout.isWeak = true;
					break;
			}
		};

		/**
		 * 初始化主题
		 */
		const initTheme = (): void => {
			switchAutoThemMode();
			darkModeMediaQuery.addEventListener("change", switchAutoThemMode);
			switchDark();
			if (layout.isGrey) switchGreyOrWeak("grey", true);
			if (layout.isWeak) switchGreyOrWeak("weak", true);
		};

		const reset = (): void => {
			layout.mainAnimation = defaultAnimation;
			layout.themeColor = defaultThemeColor;
			layout.autoThemMode = true;
			layout.isDark = false;
			layout.isGrey = false;
			layout.isWeak = false;
			initTheme();
		};

		const setDefaultLayoutSize = (): void => {
			Object.keys(defaultLayoutSize).forEach((key) => {
				layout[key] = defaultLayoutSize[key];
			});
		};

		const setSmallLayoutSize = (): void => {
			Object.keys(smallLayoutSize).forEach((key) => {
				layout[key] = smallLayoutSize[key];
			});
		};

		return {
			layout,
			setTheme,
			switchAutoThemMode,
			switchDark,
			switchGreyOrWeak,
			initTheme,
			reset,
			setDefaultLayoutSize,
			setSmallLayoutSize,
		};
	},
	{
		persist: {
			key: "store-config",
		},
	}
);
